package security.filters;

import framework.config.SecurityConfig;
import org.springframework.util.StringUtils;
import security.utils.SecurityCookieUtil;
import security.utils.SecurityTokenUtil;
import security.utils.TokenDetail;

import javax.servlet.FilterChain;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * 应用于Servlet的授权处理器
 */
public class AuthenticationServletHandler implements AuthenticationHandler {

    private final HttpServletRequest request;
    private final HttpServletResponse response;
    private final FilterChain filterChain;
    private final SecurityConfig securityConfig;

    public AuthenticationServletHandler(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain, SecurityConfig securityConfig) {
        this.request = request;
        this.response = response;
        this.filterChain = filterChain;
        this.securityConfig = securityConfig;
    }

    /**
     * get token
     *
     * @return
     */
    @Override
    public TokenDetail getRequestToken() {
        return SecurityTokenUtil.getRequestToken(this.request, this.securityConfig);
    }

    /**
     * 获取请求路径
     *
     * @return
     */
    @Override
    public String getRequestPath() {
        return request.getServletPath();
    }

    /**
     * 获取请求方法
     *
     * @return
     */
    @Override
    public String getRequestMethod() {
        return request.getMethod();
    }

    /**
     * 令牌过期提醒
     *
     * @param seconds
     */
    @Override
    public void tokenExpiredReminder(int seconds) {
        String tokenExpirationReminderHeader = securityConfig.getTokenExpirationReminderHeader();
        if (StringUtils.hasText(tokenExpirationReminderHeader)) {
            response.addHeader(tokenExpirationReminderHeader, "" + seconds);
        }
    }

    /**
     * 令牌余量提醒
     *
     * @param seconds
     */
    @Override
    public void tokenBalanceOutput(int seconds) {
        String tokenBalanceOutputHeader = securityConfig.getTokenBalanceOutputHeader();
        if (StringUtils.hasText(tokenBalanceOutputHeader)) {
            response.addHeader(tokenBalanceOutputHeader, "" + seconds);
        }
    }

    /**
     * 将新的token写入客户端
     *
     * @param token
     */
    @Override
    public void saveTokenToCookie(String token) {
        String cookieName = securityConfig.getTokenParamName();
        if (!StringUtils.hasText(cookieName)) return;

        //
        String cookiePath = securityConfig.getCookiePath();
        if (!StringUtils.hasText(cookiePath)) {
            // 当未配置时使用应用程序路径
            if (StringUtils.hasText(request.getContextPath()) && !request.getContextPath().equals("/")) {
                cookiePath = request.getContextPath();
            }
        }

        //
        Integer expires = securityConfig.getCookieMaxAge();

        // fix HttpCookie not support SameSite
        // use custom build
        StringBuffer buffer = SecurityCookieUtil.buildCookie(securityConfig, cookieName, token, cookiePath, expires);
        response.addHeader("Set-Cookie", buffer.toString());
    }
}
